import {Component, ElementRef} from '@angular/core';
import {IonicPage, NavController, NavParams, AlertController, ToastController,Events} from 'ionic-angular';
import * as _ from "lodash";
import {UnlockService} from "../../services/native/authentication/authentication.service";

@IonicPage()
@Component({
    selector: 'page-graphic-unlock',
    templateUrl: 'graphic-unlock.html',
})


export class GraphicUnlockPage {
    height: number;  //画布高度
    width: number;  //画布宽度
    chooseType: number = 3;//每行手势密码个数
    devicePixelRatio: number;
    bigCtx: any;
    lastPoint: any;
    restPoint: any[];
    bigR: number; //圆半径
    bigCirclePosition: any[]; //记录圆的索引及半径
    bigEmpty: number;//大圆之间的间隔
    smallCtx: any;
    smallR: number; // 小圆半径
    smallEmpty: number;//小圆之间的间隔
    smallCirclePoints: any[] = [];
    pswObj: any;
    canvas: HTMLCanvasElement;
    touchFlag: boolean;
    lockType: number;// 1初始化密码 2登录时验证 5更改密码
    lockTypeName: string;

    warnOutColor: string = '#e1e1e1'; //错误警告外圆颜色
    warnInnerColor: string = '#7d0000';//错误警告内圆颜色
    warnBorderColor: string = '#bd7d7d';//错误警告线颜色

    initFillColor: string = '#eee'; //初始化填充颜色
    initBorderColor: string = '#bfbfbf';//初始化边框颜色
    pointColor: string = '#35ac63'; //圆圈与圆圈连接的颜色
    normalOutColor: string = '#d7f0db';//绘图外圆颜色
    normalInnerColor: string = '#35ac63'; //绘图内圆颜色
    lineWidth: number; //连线宽度
    borderWidth: number;//圆圈边框宽度

    constructor(public navCtrl: NavController, public navParams: NavParams,
                private alertCtrl: AlertController,
                private unlockService: UnlockService,
                private toastCtrl: ToastController,
                public events:Events,
                private _elementRef: ElementRef) {
        this.navCtrl.swipeBackEnabled = false;
    }

    ionViewDidLoad() {
        let container = this._elementRef.nativeElement.querySelector('div.container');
        this.init({
            width: container.offsetWidth,
            height: container.offsetHeight,
            isHollowCircle: false,
            lockType: parseInt(this.navParams.get("lockType"))
        });
        this.navCtrl.swipeBackEnabled = false;
    }


    init(obj) {
        this.height = obj.height;
        this.width = obj.width;
        this.devicePixelRatio = 1;
        this.lockType = obj.lockType;
        this.bigR = this.convertToCurrentSize(75);
        this.smallR = this.convertToCurrentSize(13.5);
        this.lineWidth = this.convertToCurrentSize(6);
        this.bigEmpty = this.convertToCurrentSize(120);
        this.smallEmpty = this.convertToCurrentSize(20);
        this.borderWidth = this.convertToCurrentSize(1);
        this.initTip();

        this.initCanvas();

        this.lastPoint = [];
        this.touchFlag = false;
        this.canvas = document.getElementById('lockCanvas') as HTMLCanvasElement;
        this.bigCtx = this.canvas.getContext('2d');
        this.createCircle(this.bigCtx, this.bigR);
        this.bindEvent();
        this.drawSmallClock();
    }

    /*初始化两个画布的宽度与高度*/
    initCanvas() {
        let canvas = document.getElementById('lockCanvas');

        let width = this.width || 320;
        let height = this.height || 320;

        // 高清屏锁放
        canvas.style.width = width + 'px';
        canvas.style.height = height + 'px';
        canvas['height'] = height * this.devicePixelRatio;
        canvas['width'] = width * this.devicePixelRatio;

        let smallCanvas = document.getElementById('smallLockCanvas') as HTMLCanvasElement;
        // 高清屏锁放
        let smallwidth = this.convertToCurrentSize(150);
        smallCanvas.style.width = smallwidth + 'px';
        smallCanvas.style.height = smallwidth + 'px';
        smallCanvas['width'] = smallwidth;
        smallCanvas['height'] = smallwidth;
    }

    //绘制小圆
    drawSmallClock() {
        let smallCanvas = document.getElementById('smallLockCanvas') as HTMLCanvasElement;
        let smallCtx = smallCanvas.getContext('2d');
        this.smallCtx = smallCtx;
        this.createCircle(smallCtx, this.smallR, false);
    }

    initTip() {
        switch (this.lockType) {
            case OperateType.INITLOCK:
                this.lockTypeName = '设置手势密码';
                break;
            case OperateType.VAILDLOCK:
                this.lockTypeName = '校验手势密码';
                break;
            default:
                this.lockTypeName = '修改手势密码';
                break;
        }
    }

    /*绘制单个圆*/
    drawCle(ctx, x, y, r, isBig = true) {
        if (isBig) {
            ctx.beginPath();
            ctx.strokeStyle = this.initBorderColor;//圆圈默认的颜色
            ctx.lineWidth = this.borderWidth;
            ctx.arc(x, y, r, 0, Math.PI * 2, true);
            ctx.stroke();
            ctx.beginPath();//画实心圆
            ctx.arc(x, y, r - this.borderWidth, 0, Math.PI * 2, true);
            ctx.fillStyle = this.initFillColor;
            ctx.fill();//画实心圆
            ctx.stroke();
        } else {
            ctx.beginPath();
            ctx.arc(x, y, r, 0, Math.PI * 2, true);
            ctx.fillStyle = this.initFillColor;
            ctx.fill();//画实心圆
            ctx.closePath();
        }

    }

    /*绘制手势大圆圈*/
    createCircle(ctx, defineR, isBig = true) {
        let n = this.chooseType;
        let count = 0;
        let marginLeft;
        this.lastPoint = [];

        if (isBig) {
            this.bigCirclePosition = [];
            this.restPoint = [];
            marginLeft = (ctx.canvas.width - 6 * defineR - 2 * this.bigEmpty) / 2;
        } else {
            this.smallCirclePoints = [];
            marginLeft = (ctx.canvas.width - 6 * defineR - 2 * this.smallEmpty) / 2;
        }

        for (let i = 0; i < n; i++) {
            for (let j = 0; j < n; j++) {
                count++;
                if (isBig) {
                    let obj = {
                        x: marginLeft + (j * 2 + 1) * defineR + j * this.bigEmpty,
                        y: (i * 2 + 1) * defineR + i * this.bigEmpty,
                        index: count
                    };
                    this.bigCirclePosition.push(obj);
                    this.restPoint.push(obj);

                } else {
                    let obj = {
                        x: marginLeft + (j * 2 + 1) * defineR + j * this.smallEmpty,
                        y: (i * 2 + 1) * defineR + i * this.smallEmpty,
                        index: count
                    };
                    this.smallCirclePoints.push(obj);
                }
            }
        }

        let circlePosition = isBig ? this.bigCirclePosition : this.smallCirclePoints;
        ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
        for (let i = 0; i < circlePosition.length; i++) {
            this.drawCle(ctx, circlePosition[i].x, circlePosition[i].y, defineR, isBig);
        }
    }

    getPosition(e) {
        let rect = e.currentTarget.getBoundingClientRect();
        return {
            x: (e.touches[0].clientX - rect.left) * this.devicePixelRatio,
            y: (e.touches[0].clientY - rect.top) * this.devicePixelRatio
        };
    }

    /**
     * 密码比较
     * @param psw1  存储在本地的原密码
     * @param psw2  用户输入的密码
     * @returns {boolean}
     */
    checkPassword(psw1, psw2) {
        if (!psw1 || !psw2) {
            return;
        }
        let p1 = '',
            p2 = '';
        for (let i = 0; i < psw1.length; i++) {
            p1 += psw1[i].index + psw1[i].index;
        }
        for (let i = 0; i < psw2.length; i++) {
            p2 += psw2[i].index + psw2[i].index;
        }
        return p1 === p2;
    }

    storePass(psw) {
        let titleElement = document.getElementById('tipMsg');
        let smallTipMsg = document.getElementById('smallTipMsg');
        let successMsg = document.getElementById("successTipMsg");
        smallTipMsg.style.visibility = 'hidden';
        switch (this.lockType) {
            case OperateType.SAVELOCK:
                //输入密码与重置密码后，保存密码
                if (this.checkPassword(this.pswObj, psw)) {
                    this.pswObj = psw;
                    //this.drawPointAndLine(this.normalOutColor, this.normalInnerColor, '设置成功', '#000');
                    let storePwd = [];
                    this.pswObj.forEach((item) => {
                        storePwd.push({index: item.index})
                    });

                    this.unlockService.storeGraphic(JSON.stringify(storePwd));
                    window.localStorage.removeItem('lockErrorTime');
                    if(navigator.onLine) {
                        //有网的时候，才设置成功
                        successMsg.style.display = "block";
                        this.unlockService.switchGraphicLogin(true);//只有设置成功，表示没有关闭手势解锁
                    }else{
                        this.events.publish("checkNet");
                    }
                    setTimeout(() => {
                        this.navCtrl.pop();
                    }, 1000);
                    setTimeout(() => {
                        successMsg.style.display = "none";
                    }, 2000);
                } else {
                    this.drawPointAndLine(this.warnOutColor, this.warnInnerColor, this.warnBorderColor, '请绘制解锁图案', '#000');
                    smallTipMsg.style.visibility = 'visible';
                    smallTipMsg.innerHTML = '与上次绘制不一致，请重新绘制';
                    smallTipMsg.style.color = this.warnInnerColor;
                    this.lockType = OperateType.INITLOCK;//重置未初始化密码阶段
                }
                break;
            case OperateType.INITLOCK:
                //初次设置密码
                if (psw.length < 4) {
                    smallTipMsg.style.visibility = 'visible';
                    smallTipMsg.innerHTML = '至少连接四个点，请重新绘制';
                    smallTipMsg.style.color = this.warnInnerColor;
                } else {
                    this.lockType = OperateType.SAVELOCK;//第一次输入密码后，进入保存密码阶段
                    if (this.pswObj == null) {
                        this.pswObj = psw;
                    }

                    titleElement.innerHTML = '再次绘制解锁图案';
                    this.smallCtx.clearRect(0, 0, this.smallCtx.canvas.width, this.smallCtx.canvas.height);
                    let self = this;
                    let firstPwd = this.lastPoint;
                    this.smallCirclePoints.forEach((item) => {
                        this.smallCtx.lineWidth = 2;
                        this.smallCtx.beginPath();
                        this.smallCtx.arc(item.x, item.y, 5, 0, Math.PI * 2, true);
                        this.smallCtx.closePath();
                        let isExist = _.findIndex(firstPwd, (bigIitem) => {
                            return bigIitem.index === item.index
                        });
                        let smallStyle = isExist === -1 ? this.initFillColor : self.pointColor;
                        this.smallCtx.fillStyle = smallStyle;
                        this.smallCtx.fill();//画实心圆
                    })
                }

                break;
        }
    }

    drawPointAndLine(outStyle = '', innerStyle = '', borderStyle = '', tipMsg, titleStyle?) {
        this.drawLine(borderStyle, this.lastPoint[this.lastPoint.length - 1]);// 每帧画圆
        this.drawPoint(outStyle, innerStyle);

        let title = document.getElementById('tipMsg');
        title.style.color = titleStyle || innerStyle || '#000';
        title.innerHTML = tipMsg;
    }

    /**
     * 绘制圆
     * @param {string} outStyle 外圈圆颜色
     * @param {string} innerStyle 内圈圆颜色
     */
    drawPoint(outStyle = '', innerStyle = '') {
        for (let i = 0; i < this.lastPoint.length; i++) {
            this.bigCtx.lineWidth = 2;
            this.bigCtx.beginPath();
            this.bigCtx.arc(this.lastPoint[i].x, this.lastPoint[i].y, this.bigR, 0, Math.PI * 2, true);
            this.bigCtx.closePath();
            this.bigCtx.fillStyle = outStyle;
            this.bigCtx.fill();//画实心圆
        }
        for (let i = 0; i < this.lastPoint.length; i++) {
            this.bigCtx.fillStyle = innerStyle;
            this.bigCtx.beginPath();
            this.bigCtx.arc(this.lastPoint[i].x, this.lastPoint[i].y, this.bigR / 2.5, 0, Math.PI * 2, true);
            this.bigCtx.closePath();
            this.bigCtx.fill();
        }
    }

    drawLine(style, po) {
        this.bigCtx.beginPath();
        this.bigCtx.strokeStyle = style;
        this.bigCtx.lineWidth = this.lineWidth;
        if (!this.lastPoint[0]) {
            return;
        }

        this.bigCtx.moveTo(this.lastPoint[0].x, this.lastPoint[0].y);

        for (let i = 1; i < this.lastPoint.length; i++) {
            this.bigCtx.lineTo(this.lastPoint[i].x, this.lastPoint[i].y);
        }
        this.bigCtx.lineTo(po.x, po.y);
        this.bigCtx.stroke();
        this.bigCtx.closePath();
    }

    update(po) {
        this.bigCtx.clearRect(0, 0, this.bigCtx.canvas.width, this.bigCtx.canvas.height);
        this.drawLine(this.pointColor, po);// 先画连接线 后画圆形，这样可以进行覆盖

        for (let i = 0; i < this.bigCirclePosition.length; i++) {
            this.drawCle(this.bigCtx, this.bigCirclePosition[i].x, this.bigCirclePosition[i].y, this.bigR);
        }
        this.drawPoint(this.normalOutColor, this.normalInnerColor);// 每帧花轨迹
        //this.drawStatusPoint(this.clockCircleColor);// 每帧花轨迹
        for (let i = 0; i < this.restPoint.length; i++) {
            if (Math.abs(po.x - this.restPoint[i].x) < this.bigR && Math.abs(po.y - this.restPoint[i].y) < this.bigR) {
                this.drawPoint(this.normalOutColor, this.normalInnerColor);
                this.lastPoint.push(this.restPoint[i]);
                this.restPoint.splice(i, 1);
                break;
            }
        }
    }

    /*重绘圆形按钮*/
    reset() {
        this.createCircle(this.bigCtx, this.bigR);
    }

    /*绑定 手势拖拽 信息*/
    bindEvent() {
        let self = this;
        this.canvas.addEventListener('touchstart', function (e) {
            self.lastPoint = [];
            e.preventDefault();// 某些android 的 touchmove不宜触发 所以增加此行代码
            let po = self.getPosition(e);
            for (let i = 0; i < self.bigCirclePosition.length; i++) {
                if (Math.abs(po.x - self.bigCirclePosition[i].x) < self.bigR && Math.abs(po.y - self.bigCirclePosition[i].y) < self.bigR) {
                    self.touchFlag = true;
                    self.drawPoint(self.normalOutColor, self.normalInnerColor);
                    self.lastPoint.push(self.bigCirclePosition[i]);
                    self.restPoint.splice(i, 1);
                    break;
                }
            }
        }, false);
        this.canvas.addEventListener('touchmove', function (e) {
            if (self.touchFlag) {
                self.update(self.getPosition(e));
            }
        }, false);
        this.canvas.addEventListener('touchend', function () {
            if (self.touchFlag) {
                self.touchFlag = false;
                if (self.pswObj) {
                    //如果存在，则表示已经设置第一次密码
                    self.lockType = OperateType.SAVELOCK;
                }

                //重绘 界面不出现未连线的直线
                self.updateCircle();

                self.storePass(self.lastPoint);
                setTimeout(function () {
                    self.reset();
                }, 1000);
            }
        }, false);
    }

    /**
     * 重绘 界面不出现未连线的直线
     */
    updateCircle(){
        this.bigCtx.clearRect(0, 0, this.bigCtx.canvas.width, this.bigCtx.canvas.height);
        //this.drawLine(this.pointColor, po);// 先画连接线 后画圆形，这样可以进行覆盖

        this.bigCtx.beginPath();
        this.bigCtx.strokeStyle = this.pointColor;
        this.bigCtx.lineWidth = this.lineWidth;
        let userGraphicPoint=this.lastPoint,
            pointLength=userGraphicPoint.length;
        if(pointLength>1){
            //两个点以上画线
            this.bigCtx.moveTo(userGraphicPoint[0].x,userGraphicPoint[0].y);
            for (let i = 1; i < pointLength; i++) {
                this.bigCtx.lineTo(userGraphicPoint[i].x,userGraphicPoint[i].y);
            }
            this.bigCtx.stroke();
            this.bigCtx.closePath();
        }


        for (let i = 0; i < this.bigCirclePosition.length; i++) {
            this.drawCle(this.bigCtx, this.bigCirclePosition[i].x, this.bigCirclePosition[i].y, this.bigR);
        }

        this.drawPoint(this.normalOutColor, this.normalInnerColor);// 每帧花轨迹
    }
    //单位换算
    convertToCurrentSize(x: number) {
        return (this.width * x) / 1080;
    }

    //重新登录
    private promptReLogin(message) {
        var reLoginFlag = localStorage.getItem('ReLoginFlag');
        if (!reLoginFlag || reLoginFlag !== "true") {
            //先退出并跳转到登录页，然后提示
            this.unlockService.lockout(true);
            setTimeout(() => {
                let toast = this.alertCtrl.create({
                    message: message,
                    cssClass:"custom-alert",
                    buttons:[{
                        text:'确定',
                        handler:()=>{
                            location.hash = '#/login';
                        }
                    }]
                }).present();
            }, 500);
            localStorage.setItem('ReLoginFlag', "true");
        }
    }
}

//0初始化密码 2登录时验证 5更改密码
enum OperateType {
    INITLOCK = 1,//初始化密码
    SAVELOCK = 3,//保存密码
    VAILDLOCK = 4,//重新打开开关后校验密码
};
